//
// Created by ta&to on 2022/9/26.
//

#ifndef TCPSERVER_TCP_SOCKET_H
#define TCPSERVER_TCP_SOCKET_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#include "hash_util.h"
#include "tcp_config.h"
#include "tcp_connect.h"
#define NONE 0       /* No events registered. */
#define READABLE 1   /* Fire when descriptor is readable. */
#define WRITABLE 2   /* Fire when descriptor is writable. */

#if defined(__MINGW32__) || defined(__MINGW64__)
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#if defined(SOCKET_SERVER_POLL)
#include <poll.h>
#elif defined(SOCKET_SERVER_EPOLL)
#include<sys/epoll.h>
#endif
#endif
#ifdef TCPSERVER_OPEN
#include "tcp_handler.h"
#endif
#define BUF_SIZE 200


#define TCP_SOCKET_CLOSE 0b01
#define TCP_SOCKET_OPEN  0b10

#ifdef SOCKET_SERVER_SELECT
typedef void (*socket_callback_func)(struct tcp_socket_event_loop_s *hset, int fd, int n);
#else
typedef void (*socket_callback_func)(struct tcp_socket_event_loop_s *hset, int fd);
#endif
struct tcp_socket_event_handle_s{
    int fd;
    struct sockaddr_in client_addr; //客户端的地址信息
    socklen_t sin_size;
    socket_callback_func func_read;
    socket_callback_func func_write;
    int data_len;                   // 缓存数
    char *data;
};
struct socket_request_data_container{
    Leader *req_data;
};
typedef struct tcp_socket_event_handle_s tcp_socket_event_handle_t;
struct tcp_socket_event_loop_s{
    int maxfd;               // 最大的链接数(数字)
    int max_link;            // 准备就绪队列的最大链接数
    int current_link;        // 当前连接数
    int current_fd;          // 当前套接字
    int socket_fd;           //监听套接字
    void *apidata;           /* This is used for polling API specific data */
    struct timeval *tvp;
    tcp_socket_event_handle_t *func_handler;    // 局部数据
    log_t *logs;             // 日志
    struct socket_request_data_container *srdc; // 用于存放请求信息队列
#ifdef TCPSERVER_OPEN
    struct tcp_rep_pak_s *hcontxt;
#endif
#ifdef SOCKET_SERVER_SELECT
    int *select_fds; // 链接的文件描述符
#endif
#ifdef SOCKET_SERVER_POLL
    struct pollfd *poll_fds;
#endif
#ifdef SOCKET_SERVER_EPOLL
    int epoll_fd; //epoll 自身的文件描述符
    struct epoll_event *epoll_ev_fds; // 准备就绪的文件描述符
#endif
};
typedef struct tcp_socket_event_loop_s tcp_socket_event_t;
int CreateTcpSocket(log_t *logt, char *listen_ip, int listen_port, int link_num);
int Accept(log_t *logt, int socket_fd, struct sockaddr *saddr, socklen_t *slen);
int putData(log_t *logt, const int socket_fd, char* buf, int len);
int getData(log_t *logt, const int socket_fd, char* buf, int len);
void CloseAll(log_t *logt, int socket_fd, int client_fd);
int socketNonBlock(log_t *logt, int fd);
int socketBlock(log_t *logt, int fd);
#endif //TCPSERVER_TCP_SOCKET_H
